package mall.core.web;

import mall.core.ApplicationProperties;
import mall.core.Entity;
import mall.core.jdbc.Page;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author xf07b1
 * @wechat xf07b1
 * @description 扩展Servlet功能，支持编写多个Servlet，提供请求转发与重定向方法
 */
public class Controller extends HttpServlet {

    /**
     * 支持多Servlet的分发处理。
     * 同时也支持单Servlet实现，只需要子类重写该方法
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String methodName = req.getParameter("method");

        Class<? extends Controller> aClass = this.getClass();
        try {
            Method method = aClass.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.setAccessible(true);
            method.invoke(this, req, resp);
        } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 请求转发，会拼接视图的前后缀。
     * 例如：/index -> /WEB-INF/views/index.jsp
     */
    protected void forward(String view, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher(req.getContextPath() + ApplicationProperties.VIEW_PREFIX + view + ApplicationProperties.VIEW_SUFFIX).forward(req, resp);
    }


    /**
     * 重定向，不拼接视图的前后缀。
     * 例如：/index -> /index
     */
    protected void redirect(String view, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect(req.getContextPath() + view);
    }

    /**
     * 从请求中获取分页对象
     */
    protected <T> Page<T> getParameterForPage(HttpServletRequest request) {
        String pageNumString = request.getParameter("pageNum");
        String pageSizeString = request.getParameter("pageSize");

        Page<T> page = new Page<>();

        if (pageNumString != null && pageSizeString != null && !pageNumString.trim().isEmpty() && !pageSizeString.trim().isEmpty()) {
            page.setPageNum(Integer.parseInt(pageNumString.trim()));
            page.setPageSize(Integer.parseInt(pageSizeString.trim()));
        }

        return page;
    }


    /**
     * 从请求中获取实体类
     */
    protected Entity getParameterForEntity(HttpServletRequest request) {
        throw new RuntimeException("method not support");
    }


    /**
     * 分页信息写入request
     */
    protected <T> void setPageAttribute(HttpServletRequest request, Page<T> page) {
        request.setAttribute("list", page.getList());
        request.setAttribute("pageNum", page.getPageNum());
        request.setAttribute("pageSize", page.getPageSize());
        request.setAttribute("total", page.getTotal());
        request.setAttribute("pages", page.getPages());
    }
}
